
public class ManhattanDistanceCache implements DistanceCache 
{
	private int[][] boxManhattanDistanceMatrix;
	
	public ManhattanDistanceCache( BoardImplFast board )
	{
		boxManhattanDistanceMatrix = new int[ board.getXLength() ][ board.getYLength() ];
		
		Cord[] goals = board.getGoals();
		
		for ( int x = 0; x < board.getXLength(); x++ )
		{
			for ( int y = 0; y < board.getYLength(); y++ )
			{
				boxManhattanDistanceMatrix[ x ][ y ] = minimumManhattanDistance(board, new CordImpl(x,y), goals);
			}
		}
		
	}
	
	private int minimumManhattanDistance( Board board, Cord start, Cord[] goals )
	{
		int min = Integer.MAX_VALUE;
		
		boolean found = false;
		for( Cord goal : goals )
		{ 
			if (!found)
			{
				min = manhattanDistance(start, goal);
				found = true;
			}
			else
			{
				min = Math.min( min , manhattanDistance(start, goal) );
			}

		}
		
		return min;
	}
	
	public static int manhattanDistance( Cord c1, Cord c2 )
	{
		return (Math.abs( c1.getX()-c2.getX() ) + Math.abs( c1.getY()-c2.getY() ));
	}
	
	@Override
	public int getDistancePlayer(Cord start, Cord goal) 
	{
		return manhattanDistance(start, start);
	}

	@Override
	public int getDistanceBox(Cord start, Cord goal) 
	{
		return manhattanDistance(start, start);
	}

	@Override
	public int minimumBoxDistance(Board board, Cord start, Cord[] goals) 
	{
//		return minimumPlayerDistance(board, start, goals);
		return boxManhattanDistanceMatrix[ start.getX() ][ start.getY() ];
	}

	@Override
	public int minimumPlayerDistance(Board board, Cord start, Cord[] goals) 
	{
		return minimumManhattanDistance(board, start, goals);
	}

}
